package Pattern.ObserverPattern.program6;

import java.util.ArrayList;

public class Tests {
    public static void main(String[] args) {
        // create objects for testing
        AverageScoreDisplay averageScoreDisplay = new AverageScoreDisplay();
        CurrentScoreDisplay currentScoreDisplay = new CurrentScoreDisplay();

        // pass the displays to cricket data
        CricketData cricketData = new CricketData();

        // register display elements
        cricketData.registerObserver(averageScoreDisplay);
        cricketData.registerObserver(currentScoreDisplay);

// in real app you would have some logic to call this function when data changes
        cricketData.dataChanged();

        //remove an observer
        cricketData.unregisterObserver(currentScoreDisplay);

// now only currentScoreDisplay gets the  notification
        cricketData.dataChanged();
    }
}

interface Subject {
    public void registerObserver(Observer o);

    public void unregisterObserver(Observer o);

    public void notifyObservers();
}

class CricketData implements Subject {
    int runs;
    int wickets;
    float overs;
    ArrayList<Observer> observerList = new ArrayList<Observer>();

    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    @Override
    public void unregisterObserver(Observer o) {
        observerList.remove(o);
    }

    @Override
    public void notifyObservers() {
        for(Observer observer:observerList){
            observer.update(runs,wickets,overs);
        }
    }

    // get latest runs from stadium
    private int getLatestRuns() {
        return 90;
    }

    // get latest wickets from stadium
    private int getLatestWickets() {
        return 2;
    }

    // get latest overs from stadium
    private float getLatestOvers() {
        return (float) 10.2;
    }

    // This method is used update displays when data changes
    public void dataChanged() {
        //get latest data
        runs = getLatestRuns();
        wickets = getLatestWickets();
        overs = getLatestOvers();
        notifyObservers();
    }
}

interface Observer {
    void update(int runs, int wickets, float overs);
}

class AverageScoreDisplay implements Observer {
    private float runRate;
    private int predictedScore;

    public void update(int runs, int wickets, float overs) {
        this.runRate = (float) runs / overs;
        this.predictedScore = (int) (this.runRate * 50);
        display();
    }

    private void display() {
        System.out.println("失分率: "+ runRate);
        System.out.println("预计分数: "+ predictedScore);
    }
}

class CurrentScoreDisplay implements Observer {
    private int runs, wickets;
    private float overs;

    public void update(int runs, int wickets, float overs) {
        this.runs = runs;
        this.wickets = wickets;
        this.overs = overs;
        display();
    }

    private void display() {
        System.out.println("runs: "+runs+" wickets "+wickets+" overs "+overs);
    }
}


